package lock.sales.producer;

import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @AUTHOR LYF
 * @DATE 2022/3/19
 * @VERSION 1.0
 * @DESC
 */

class Item{
    Integer no;
    String name;
    Date produceTime;
    String producePerson;

    public Item(Integer no, String name, Date produceTime, String producePerson) {
        this.no = no;
        this.name = name;
        this.produceTime = produceTime;
        this.producePerson = producePerson;
    }

    public Integer getNo() {
        return no;
    }

    public void setNo(Integer no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getProduceTime() {
        return produceTime;
    }

    public void setProduceTime(Date produceTime) {
        this.produceTime = produceTime;
    }

    public String getProducePerson() {
        return producePerson;
    }

    public void setProducePerson(String producePerson) {
        this.producePerson = producePerson;
    }

    @Override
    public String toString() {
        return "Item{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", produceTime=" + produceTime +
                ", producePerson='" + producePerson + '\'' +
                '}';
    }
}

class Resource{
      volatile boolean flag = true;
      private volatile int no=1;
      ArrayList<Item> resourceList = new ArrayList<>();//线程安全问题？
      ReentrantLock lock = new ReentrantLock();
      Condition produceMutex = lock.newCondition();
      Condition consumeMutex = lock.newCondition();

      void produce(){
//          if(ProducerConsumerDemo.count>10){
//              System.out.println("已生产10,停产");
//              flag=false;
//          }


          while(flag){
              if(ProducerConsumerDemo.count>1000){
                  System.out.println("已生产1000,停产");
                  flag=false;
                  break;
              }
              lock.lock();//上锁
              try{
                  while(resourceList.size()!=0)
                      produceMutex.await();//当资源够的时候，就等待，先不生产

                  Integer random = new Random().nextInt(3);//随机生产十个,生成的数量无所谓
                  random++;//保证大于1个
                  ProducerConsumerDemo.count+=random;
                  System.out.println(Thread.currentThread().getName()+"准备生产"+random+"个产品");
                  for(int i=0;i<random;i++){
                      resourceList.add(new Item(no,"Product-"+no,new Date(),
                              Thread.currentThread().getName()));
                      no++;
                  }

                  consumeMutex.signalAll();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }finally {
                  lock.unlock();
              }
          }
      }

      void consumer(){
          while (flag){
              lock.lock();
              try{
                  while(resourceList.size()==0)
                      consumeMutex.await();//等待消费

                  Item item = resourceList.remove(0);
                  System.out.println(Thread.currentThread().getName()+"::消费了"+item);

                  if(resourceList.size()==0)
                      produceMutex.signalAll();// 提醒生产者生产

              } catch (InterruptedException e) {
                  e.printStackTrace();
              }finally {
                  lock.unlock();
              }
          }

      }
}

class Task implements Runnable{
    String name;
    Resource resource;
    public Task(String name,Resource resource) {
        this.name = name;
        this.resource = resource;
    }

    @Override
    public void run() {
        if(name.contains("Product")){
            resource.produce();
        }else
        {
            resource.consumer();
        }
    }
}

public class ProducerConsumerDemo {
    volatile static int count = 1;
    public static void main(String[] args) {
        Resource resource = new Resource();

//        new Thread(()->{
//            resource.produce();
//        },"Product-1").start();
//
//        new Thread(()->{
//            resource.consumer();
//        },"Consumer-1").start();
//
//        new Thread(()->{
//            resource.consumer();
//        },"Consumer-2").start();


        Executor executor =new ThreadPoolExecutor(5,9,10, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());

//        executor.execute(()->{
//           // resource.consumer();
//
//        });
//
//        executor.execute(()->{
//            resource.consumer();
//        });
//
//        executor.execute(()->{
//            resource.produce();
//        });

        executor.execute(new Task("Product-1",resource));
        executor.execute(new Task("Product-2",resource));
        executor.execute(new Task("Consumer-1",resource));
        executor.execute(new Task("Consumer-2",resource));
        executor.execute(new Task("Consumer-3",resource));
        executor.execute(new Task("Consumer-4",resource));


    }
}
